/**
 * 
 */
package edu.buffalo.son.garman.entity;

import java.util.HashMap;

/**
 * @author sravanku
 *
 */
public class PersonCounts {
    
    private static final String CKD_LBL        = "CKD";
    private static final String HF_DM_CAD_LBL  = "HF & DM & CAD";
    private static final String HF_CAD_LBL     = "HF & CAD";
    private static final String HF_DM_LBL      = "HF & DM";
    private static final String HF_LBL         = "HF";
    private static final String CAD_DM_LBL     = "CAD & DM";
    private static final String CAD_LBL        = "CAD";
    private static final String DM_LBL         = "DM";
    private static final String COPD_LBL       = "COPD";
    private static final String DEP_LBL        = "DEP";
    private static final String ASTH_LBL       = "ASTH";
    private static final String CV_Risk_LBL    = "CV Risk";
    private static final String At_Risk_LBL    = "At Risk";
    private static final String Healthy_LBL    = "Healthy";
    
    public enum IndexAlgorithm {
        OLD,
        NEW;
    }
    
    private final String personId;
    private HashMap<String, Integer> diseaseCounts = new HashMap<String, Integer>() {
        // Overridden to simplify the code.
        @Override
        public Integer get(Object key) {
            Integer retValue = super.get(key);
            return (retValue == null) ? 0 : retValue;
        }
    };
    private HashMap<String, Integer> claimCounts = new HashMap<String, Integer>() {
        // Overridden to simplify the code.
        @Override
        public Integer get(Object key) {
            Integer retValue = super.get(key);
            return (retValue == null) ? 0 : retValue;
        }        
    };
    
    public PersonCounts(String personId) {
        this.personId = personId;
    }
    
    public void updateDiseaseCounts(String disease) {
        Integer count = diseaseCounts.get(disease);
        if(count == null) {
            count = 0;
        }
        diseaseCounts.put(disease, count + 1);
    }
    
    public void updateClaimCounts(String claimType) {
        Integer count = claimCounts.get(claimType);
        if(count == null) {
            count = 0;
        }
        claimCounts.put(claimType, count + 1);
    }
    
    public int getClaimCounts(String claimType) {
        Integer count = claimCounts.get(claimType);
        return (count==null) ? 0 : count;
    }
    
    public int getDiseaseCounts(String diseaseType) {
        Integer count = diseaseCounts.get(diseaseType);
        return (count==null) ? 0 : count;
    }
    
    /**
     * Returns Zero if the count is zero, or the object is not present
     * Returns One  if the count is > 1 
     * @param key
     * @return 0 (or) 1
     */
    public Integer getPresense(String key) {
        int retValue = diseaseCounts.get(key);
        return (retValue <= 0) ? 0 : 1;
    }
    
    public String getCategory(IndexAlgorithm algorithm) {
        if(algorithm == IndexAlgorithm.OLD) {
            return getCategoryOld();
        }
        else if(algorithm == IndexAlgorithm.NEW) {
            return getCategory();
        }
        else {
            throw new IllegalArgumentException();
        }
    }
    
    /**
     * New Algorithm
     * @return
     */
    private String getCategory() {
        
        //Algorithm
        int CKD_Count = getDiseaseCounts("CKD");
        int HF_Count  = getDiseaseCounts("HF");
        int CAD_Count = getDiseaseCounts("CAD");
        int DM_Count  = getDiseaseCounts("DM");
        int COPD_Count= getDiseaseCounts("COPD");
        int DEP_Count = getDiseaseCounts("DEP");
        int ASTH_Count= getDiseaseCounts("ASTH");
        int HTN_Count = getDiseaseCounts("HTN");
        int LD_Count  = getDiseaseCounts("LD");
        
        String category;
        
        if(CKD_Count >= 1) {
            category = CKD_LBL;
        }
        else if (HF_Count >=1 && CAD_Count >= 1 && DM_Count >= 1) {
            category = HF_DM_CAD_LBL;
        }
        else if (HF_Count >=1 && CAD_Count >= 1) {
            category = HF_CAD_LBL;
        }
        else if (HF_Count >=1 && DM_Count >= 1) {
            category = HF_DM_LBL;
        }
        else if (HF_Count >=1) {
            category = HF_LBL;
        }
        else if (CAD_Count >= 1 && DM_Count >= 1) {
            category = CAD_DM_LBL;
        }
        else if (CAD_Count >= 1) {
            category = CAD_LBL;
        }
        else if (DM_Count >= 1) {
            category = DM_LBL;
        }
        else if (COPD_Count >= 1) {
            category = COPD_LBL;
        }
        else if (DEP_Count >= 1) {
            category = DEP_LBL;
        }
        else if (ASTH_Count >= 1) {
            category = ASTH_LBL;
        }
        else if (HTN_Count >= 2 || LD_Count >= 2) {
            category = CV_Risk_LBL;
        }
        else if (HTN_Count == 1 || LD_Count == 1) {
            category = At_Risk_LBL;
        }
        else {
            category = Healthy_LBL;
        }
        
        return category;
    }
    
    /**
     * Old Algorithm.
     * @return
     */
    private String getCategoryOld() {
        
        //Algorithm
        int CKD_Count = getDiseaseCounts("CKD");
        int HF_Count  = getDiseaseCounts("HF");
        int CAD_Count = getDiseaseCounts("CAD");
        int DM_Count  = getDiseaseCounts("DM");
        int COPD_Count= getDiseaseCounts("COPD");
        int DEP_Count = getDiseaseCounts("DEP");
        int ASTH_Count= getDiseaseCounts("ASTH");
        int HTN_Count = getDiseaseCounts("HTN");
        int LD_Count  = getDiseaseCounts("LD");
        
        String category;
        
        if(CKD_Count >= 1) {
            category = CKD_LBL;
        }
        else if (HF_Count >=1 && CAD_Count >= 1 && DM_Count >= 1) {
            category = HF_DM_CAD_LBL;
        }
        else if (HF_Count >=1 && DM_Count >= 1) {
            category = HF_DM_LBL;
        }
        else if (CAD_Count >= 1 && DM_Count >= 1) {
            category = CAD_DM_LBL;
        }
        else if (HF_Count >=1 && CAD_Count >= 1) {
            category = HF_CAD_LBL;
        }
        else if (HF_Count >=1) {
            category = HF_LBL;
        }
        else if (CAD_Count >= 1) {
            category = CAD_LBL;
        }
        else if (DM_Count >= 1) {
            category = DM_LBL;
        }
        else if (COPD_Count >= 1) {
            category = COPD_LBL;
        }
        else if (ASTH_Count >= 1) {
            category = ASTH_LBL;
        }
        else if (HTN_Count >= 2 || LD_Count >= 2) {
            category = CV_Risk_LBL;
        }
        else if (HTN_Count == 1 || LD_Count == 1) {
            category = At_Risk_LBL;
        }
        else if (DEP_Count >= 1) {
            category = DEP_LBL;
        }
        else {
            category = Healthy_LBL;
        }
        
        return category;
    }


    @Override
    public String toString() {
        return "PersonCounts [personId=" + personId + ", category=" 
                + getCategory() + ", diseaseCounts=" + diseaseCounts 
                + ", claimCounts=" + claimCounts + "]";
    }
    
    public static String getOutputFormatHeader() {
        String header = "PersonId" + "|" 
                + "-Label-" + "|" // Classification Label.
                + "IP#" + "|"
                + "ER#" + "|"
                + "OP#" + "|"
                + "AS#" + "|"
                + "CKD#" + "|"
                + "HF#"  + "|"
                + "CAD#" + "|"
                + "DM#"  + "|"
                + "COPD#" + "|"
                + "DEP#" + "|"
                + "ASTH#" + "|"
                + "HTN#" + "|"
                + "LD#" + "|"
                + "CKD" + "|"
                + "HF"  + "|"
                + "CAD" + "|"
                + "DM"  + "|"
                + "COPD" + "|"
                + "DEP" + "|"
                + "ASTH" + "|"
                + "HTN" + "|"
                + "LD" + "|"
                + "Segment" + "|"
                + "Chronic";
        return header;
    }
    
    public String getOutputFormat(IndexAlgorithm algorithm) {
        
        String category = getCategory(algorithm);
        String segment;
        String chronic = "Chronic";
        if(category.equals(CKD_LBL) || category.equals(HF_DM_CAD_LBL)
                || category.equals(HF_CAD_LBL) || category.equals(HF_DM_LBL)
                || category.equals(HF_LBL)) {
            segment = "System Failure";
        }
        else if(category.equals(CAD_DM_LBL) || category.equals(CAD_LBL)
                || category.equals(DM_LBL) || category.equals(COPD_LBL)
                || category.equals(DEP_LBL) || category.equals(ASTH_LBL)) {
            segment = "Chronic";
        }
        else if(category.equals(CV_Risk_LBL) || category.equals(At_Risk_LBL)){
            segment = "At Risk";
            chronic = "No Chronic";
        }
        else {
            segment = "Healthy";
            chronic = "No Chronic";
        }
        
        String retValue = this.personId + "|" 
                    + category + "|"
                    + claimCounts.get("IP") + "|"
                    + claimCounts.get("ER") + "|"
                    + claimCounts.get("OP") + "|"
                    + claimCounts.get("AS") + "|"
                    + diseaseCounts.get("CKD") + "|"
                    + diseaseCounts.get("HF" ) + "|"
                    + diseaseCounts.get("CAD") + "|"
                    + diseaseCounts.get("DM" ) + "|"
                    + diseaseCounts.get("COPD") + "|"
                    + diseaseCounts.get("DEP") + "|"
                    + diseaseCounts.get("ASTH") + "|"
                    + diseaseCounts.get("HTN") + "|"
                    + diseaseCounts.get("LD" ) + "|"
                    + getPresense("CKD") + "|"
                    + getPresense("HF" ) + "|"
                    + getPresense("CAD") + "|"
                    + getPresense("DM" ) + "|"
                    + getPresense("COPD") + "|"
                    + getPresense("DEP") + "|"
                    + getPresense("ASTH") + "|"
                    + getPresense("HTN") + "|"
                    + getPresense("LD" ) + "|"
                    + segment + "|" 
                    + chronic;
        
        return retValue;
    }
    
    
}
